#include <QtGui>

#include <iostream>

#include "invader_window.h"
#include "invader_frame.h"
#include "titlescreen_frame.h"
#include "gameoverscreen_frame.h"
#include "gamemenu_frame.h"
#include "numeric_label.h"
#include "icon_label.h"
#include "media.h"

InvaderWindow::InvaderWindow ()
{
  resize (530, 440);
  setMaximumSize (530, 440);
  setMinimumSize (530, 440);

  QGridLayout *gl = new QGridLayout (this);

  _gameFrame = new InvaderFrame (this);
  _gameFrame->setFocusPolicy (Qt::ClickFocus);
  gl->addWidget (_gameFrame, 1, 0, 1, 2);
  connect (_gameFrame, SIGNAL (gameOver ()),
           this, SLOT (gameOver ()));
  connect (_gameFrame, SIGNAL (endDemoMode ()),
           this, SLOT (displayTitleScreen ()));
  connect (_gameFrame, SIGNAL (displayMenu ()),
           this, SLOT (displayGameMenu ()));

  _demoTimer = new QTimer (this);
  _demoTimer->setInterval (5000);
  connect (_demoTimer, SIGNAL (timeout ()), this, SLOT (startDemo ()));

  _titleScreen = new TitleScreen (this);
  _titleScreen->setFocusPolicy (Qt::ClickFocus);
  gl->addWidget (_titleScreen, 1, 0, 1, 2);
  connect (_titleScreen, SIGNAL (beginNewGame ()),
           this, SLOT (beginNewGame ()));
  connect (_titleScreen, SIGNAL (quit ()), this, SLOT (quitGame ()));
  connect (_titleScreen, SIGNAL (shown ()),
           _demoTimer, SLOT (start ()));
  connect (_titleScreen, SIGNAL (shown ()),
           _demoTimer, SLOT (start ()));
  connect (_titleScreen, SIGNAL (activity ()),
           this, SLOT (titleScreenActivity ()));
  connect (_titleScreen, SIGNAL (clearHighscore ()),
           this, SLOT (clearHighscore ()));

  _gameMenu = new GameMenu (this);
  gl->addWidget (_gameMenu, 1, 0, 1, 2);
  connect (_gameMenu, SIGNAL (resume ()), this, SLOT (displayGame ()));
  connect (_gameMenu, SIGNAL (restart ()), this, SLOT (beginNewGame ()));
  connect (_gameMenu, SIGNAL (clearHighscore ()),
           this, SLOT (clearHighscore ()));
  connect (_gameMenu, SIGNAL (quit ()), this, SLOT (quitGame ()));

  _scoreLabel = new NumericLabel ("score", this);
  gl->addWidget (_scoreLabel, 0, 0, Qt::AlignLeft);
  connect (_gameFrame, SIGNAL (scoreChanged (int)),
           _scoreLabel, SLOT (setValue (int)));

  _highscoreLabel = new NumericLabel ("highscore", this);
  gl->addWidget (_highscoreLabel, 0, 1, Qt::AlignRight);

  _livesLabel = new IconLabel (MEDIA_DIR TANK_IMG, "lives", 3, this);
  gl->addWidget (_livesLabel, 2, 0, 1, 2);
  connect (_gameFrame, SIGNAL (livesChanged (int)),
           _livesLabel, SLOT (setValue (int)));

  _gameOverScreen = new GameOverScreen (this);
  gl->addWidget (_gameOverScreen, 1, 0, 1, 2);
  connect (_gameOverScreen, SIGNAL (hideScreen ()),
           this, SLOT (displayTitleScreen ()));

  setWindowTitle (tr ("Space Invaders"));
  setLayout (gl);
  QPalette palette;
  palette.setColor (QPalette::Window, QColor::fromRgb (0, 0, 0));
  setPalette (palette);

  displayTitleScreen ();
}

void InvaderWindow::titleScreenActivity ()
{
  if (_demoTimer->isActive ())
    _demoTimer->start ();
}

void InvaderWindow::beginNewGame ()
{
  QFile hsFile (".highscore.dat");
  if (hsFile.exists ()) {
    hsFile.open (QIODevice::ReadOnly);
    QDataStream hsDS (&hsFile);
    int hs;
    hsDS >> hs;
    hsFile.close ();
    _highscoreLabel->setValue (hs);
  }

  _demoTimer->stop ();
  _gameFrame->reset ();
  displayGame ();
  _gameFrame->start ();
}

void InvaderWindow::startDemo ()
{
  _demoTimer->stop ();
  _gameFrame->reset (true);
  displayGame ();
  _gameFrame->start ();
}

void InvaderWindow::gameOver ()
{
  if (_scoreLabel->getValue () > _highscoreLabel->getValue ()) {
    QFile hsFile (".highscore.dat");
    hsFile.open (QIODevice::WriteOnly | QIODevice::Truncate);
    QDataStream hsDS (&hsFile);
    hsDS << _scoreLabel->getValue ();
    hsFile.close ();
  }

  displayGameOverScreen ();
}

void InvaderWindow::quitGame ()
{
  QCoreApplication::quit ();
}

void InvaderWindow::displayTitleScreen ()
{
  _gameFrame->setVisible (false);
  _gameFrame->stop ();
  _scoreLabel->setVisible (false);
  _highscoreLabel->setVisible (false);
  _livesLabel->setVisible (false);
  _titleScreen->setVisible (true);
  _gameMenu->setVisible (false);
  _gameOverScreen->setVisible (false);
  _titleScreen->setFocus ();
}

void InvaderWindow::displayGameOverScreen ()
{
  _gameFrame->setVisible (false);
  _gameFrame->stop ();
  _scoreLabel->setVisible (false);
  _highscoreLabel->setVisible (false);
  _livesLabel->setVisible (false);
  _titleScreen->setVisible (false);
  _gameMenu->setVisible (false);
  _gameOverScreen->setVisible (true);
  _gameOverScreen->setFocus ();
}

void InvaderWindow::displayGame ()
{
  _gameFrame->setVisible (true);
  _gameFrame->start ();
  _scoreLabel->setVisible (true);
  _highscoreLabel->setVisible (true);
  _livesLabel->setVisible (true);
  _titleScreen->setVisible (false);
  _gameMenu->setVisible (false);
  _gameOverScreen->setVisible (false);
  _gameFrame->setFocus ();
}

void InvaderWindow::displayGameMenu ()
{
  _gameFrame->setVisible (false);
  _gameFrame->stop ();
  _scoreLabel->setVisible (false);
  _highscoreLabel->setVisible (false);
  _livesLabel->setVisible (false);
  _titleScreen->setVisible (false);
  _gameMenu->setVisible (true);
  _gameOverScreen->setVisible (false);
  _gameMenu->setFocus ();
}

void InvaderWindow::clearHighscore ()
{
  QFile hsFile (".highscore.dat");
  hsFile.remove ();
  _highscoreLabel->setValue (0);
}
